using System;
using Microsoft.SPOT;
using nRF24L10P;
using nRF24L10P.Register;
using System.Reflection;
using System.Text;
using nRF24L10P.Helper;
using System.Threading;
using nRF24L10P.Roles;
using YFSoft.Hardware.NetDIY;
namespace NetDIYTest
{
    class SimpleTest
    {
        nRF24L10P.nRF24L10P device;
        private object syncRoot;
        public SimpleTest()
        {
            syncRoot = new object();
        }
        public void Init()
        {

            device = new nRF24L10P.nRF24L10P(Microsoft.SPOT.Hardware.SPI.SPI_module.SPI1, CPU.Pins.PA2, CPU.Pins.PB4, CPU.Pins.PB3);
        }

        public void DumpRegisters()
        {

            //var x = device.Registers.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
            RegisterBase[] innerItems = device.Registers.GetType().GetField("items", BindingFlags.NonPublic|BindingFlags.Instance).GetValue(device.Registers) as RegisterBase[];

            foreach (var item in innerItems)
            {
                dumpPropertys(item);
            }
        }

        private void dumpPropertys(object source)
        {
            Type t=source.GetType();
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append("--------------");
            sb.Append(t.Name);
            sb.AppendLine("--------------");
            foreach (var item in t.GetMethods())
            {
                if (item.Name.Substring(0,4)=="get_")// this is the get method for property
                {
                    
                    string name = item.Name.Substring(4, item.Name.Length-4);
                    object returnValue = item.Invoke(source, null);
                    string value = returnValue.ToString();
                    sb.Append(name);
                    sb.Append(" = ");
                    if (returnValue.GetType()==typeof(byte[]))
                    {
                        dumpBytes(returnValue as byte[], sb);
                    }
                    else
                    {
                        sb.AppendLine(value);
                    }
                    
                }
            }
            Debug.Print(sb.ToString());
        }

        private void dumpBytes(byte[] value,StringBuilder sb)
        {
            for (int i = 0; i < value.Length; i++)
            {
                sb.Append(DebugHelper.Byte2Hex(value[i]));
                sb.Append(" ");
            }
            sb.Length--;
            sb.AppendLine();
        }


        
        public void SimpleReceiveTest()
        {
            configDevice();
            nRF24L10P.Roles.SimpleReceiverRole receiver = new nRF24L10P.Roles.SimpleReceiverRole();
            receiver.AttachDevice(device);
            receiver.Address = new byte[] { 0xAB, 0xCD, 0xAB, 0xCD, 0x71 };
            receiver.DataArrived += receiver_DataArrived;
            receiver.Start();
            //Debug.Print("Listening...");
            //DumpRegisters();

            while (true)
            {
                
            }
        }


        public void SimpleSendTest()
        {
            configDevice();
            nRF24L10P.Roles.SimpleSendRole sender = new nRF24L10P.Roles.SimpleSendRole();
            sender.AttachDevice(device);
            sender.Address = new byte[] { 0x54, 0x4d, 0x52, 0x68, 0x7C };
            
            sender.Start();
            int count = 0;
            while (true)
            {
                byte[] payload = Encoding.UTF8.GetBytes("Hello World "+(count++).ToString());
                if(sender.Send(payload))
                {
                    Debug.Print("Send complete");
                }
                else
	            {
                    Debug.Print("Send failed");
	            }
                Thread.Sleep(1000);
            }
        }

        private void configDevice()
        {
            device.Config.RadioChannel = 1;
            device.Config.DataRate = DeviceConfig.NRFDataRate.DR1Mbps;
            device.Config.CRCEncodingScheme = DeviceConfig.CRCEncodingSchemeEnum.SingleByte;
            device.Config.AutoRetransmitCount = 5;
            device.Config.AutoRetransmitDelay = DeviceConfig.AutoRetransmitDelayEnum.Delay500uS;
        }
        void receiver_DataArrived(byte[] buffer)
        {
            StringBuilder sb=new StringBuilder();
            dumpBytes(buffer, sb);
            Debug.Print("Data Received, Data =" + sb.ToString());
        }

        public void SimpleSendReceiveTest()
        {
            configDevice();
            SendReceiveRole sendReceive = new nRF24L10P.Roles.SendReceiveRole();
            sendReceive.AttachDevice(device);
            sendReceive.DataArrived += sendReceive_DataArrived;
            sendReceive.SendAddress = new byte[] { 0x54, 0x4d, 0x52, 0x68, 0x7C };
            sendReceive.ReceiveAddress = new byte[] { 0xAB, 0xCD, 0xAB, 0xCD, 0x71 };
            sendReceive.Start();
            int count=0;
            while (true)
            {
                string content="Payload, Count="+(count++).ToString();
                lock (syncRoot)
                {
                    if(sendReceive.Send(Encoding.UTF8.GetBytes(content)))
                    {
                        Debug.Print("data sent success");
                    }
                    else
                    {
                        Debug.Print("failed to send data");
                    }
                }
                
                Thread.Sleep(1000);
            }
        }

        void sendReceive_DataArrived(byte[] data)
        {
            lock (syncRoot)
            {
                StringBuilder sb = new StringBuilder();
                dumpBytes(data, sb);
                Debug.Print("Data Received, Data =" + sb.ToString());
            }
            
        }
    }
}
